from typing import List, Optional, Dict
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from fastapi import HTTPException, status

from app.models.permission import Permission
from app.schemas.permission import PermissionCreate, PermissionUpdate, PermissionByCategory


class PermissionService:
    """权限服务类"""
    
    def __init__(self, db: Session):
        self.db = db
    
    def get_by_id(self, permission_id: int) -> Optional[Permission]:
        """根据ID获取权限"""
        return self.db.query(Permission).filter(Permission.id == permission_id).first()
    
    def get_by_name(self, name: str) -> Optional[Permission]:
        """根据名称获取权限"""
        return self.db.query(Permission).filter(Permission.name == name).first()
    
    def get_all(self, skip: int = 0, limit: int = 100, is_active: Optional[bool] = None) -> List[Permission]:
        """获取所有权限"""
        query = self.db.query(Permission)
        if is_active is not None:
            query = query.filter(Permission.is_active == is_active)
        return query.order_by(Permission.category, Permission.created_at).offset(skip).limit(limit).all()
    
    def search_permissions(self, keyword: str, skip: int = 0, limit: int = 100) -> List[Permission]:
        """搜索权限"""
        return self.db.query(Permission).filter(
            or_(
                Permission.name.contains(keyword),
                Permission.display_name.contains(keyword),
                Permission.description.contains(keyword),
                Permission.category.contains(keyword)
            )
        ).offset(skip).limit(limit).all()
    
    def get_by_category(self, category: str) -> List[Permission]:
        """根据分类获取权限"""
        return self.db.query(Permission).filter(
            and_(
                Permission.category == category,
                Permission.is_active == True
            )
        ).all()
    
    def get_categories(self) -> List[str]:
        """获取所有权限分类"""
        categories = self.db.query(Permission.category).filter(
            Permission.is_active == True
        ).distinct().all()
        return [cat[0] for cat in categories]
    
    def get_grouped_by_category(self) -> List[PermissionByCategory]:
        """按分类分组获取权限"""
        permissions = self.db.query(Permission).filter(
            Permission.is_active == True
        ).order_by(Permission.category, Permission.created_at).all()
        
        grouped = {}
        for perm in permissions:
            if perm.category not in grouped:
                grouped[perm.category] = []
            grouped[perm.category].append(perm)
        
        return [
            PermissionByCategory(category=cat, permissions=perms)
            for cat, perms in grouped.items()
        ]
    
    def create_permission(self, permission_data: PermissionCreate) -> Permission:
        """创建权限"""
        # 检查权限名称是否已存在
        if self.get_by_name(permission_data.name):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="权限名称已存在"
            )
        
        # 检查系统权限
        if permission_data.is_system:
            # 只有超级管理员才能创建系统权限
            pass  # 这里需要在API层做权限检查
        
        db_permission = Permission(
            name=permission_data.name,
            display_name=permission_data.display_name,
            description=permission_data.description,
            category=permission_data.category,
            action=permission_data.action,
            resource=permission_data.resource,
            is_active=permission_data.is_active,
            is_system=permission_data.is_system
        )
        
        self.db.add(db_permission)
        self.db.commit()
        self.db.refresh(db_permission)
        
        return db_permission
    
    def update_permission(self, permission_id: int, permission_data: PermissionUpdate) -> Permission:
        """更新权限"""
        permission = self.get_by_id(permission_id)
        if not permission:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="权限不存在"
            )
        
        # 检查系统权限
        if permission.is_system:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="系统权限不允许修改"
            )
        
        # 检查权限名称是否被占用
        if permission_data.name and permission_data.name != permission.name:
            existing_permission = self.get_by_name(permission_data.name)
            if existing_permission:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="权限名称已存在"
                )
        
        # 更新权限字段
        update_data = permission_data.dict(exclude_unset=True)
        for field, value in update_data.items():
            setattr(permission, field, value)
        
        self.db.commit()
        self.db.refresh(permission)
        
        return permission
    
    def delete_permission(self, permission_id: int) -> bool:
        """删除权限"""
        permission = self.get_by_id(permission_id)
        if not permission:
            return False
        
        # 检查系统权限
        if permission.is_system:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="系统权限不允许删除"
            )
        
        # 检查是否有角色在使用这个权限
        if permission.roles:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="权限正在被角色使用，无法删除"
            )
        
        self.db.delete(permission)
        self.db.commit()
        return True
    
    def get_permission_tree(self) -> Dict[str, Dict]:
        """获取权限树形结构"""
        permissions = self.db.query(Permission).filter(
            Permission.is_active == True
        ).all()
        
        tree = {}
        for perm in permissions:
            if perm.category not in tree:
                tree[perm.category] = {
                    "actions": set(),
                    "resources": set(),
                    "permissions": []
                }
            
            tree[perm.category]["actions"].add(perm.action)
            tree[perm.category]["resources"].add(perm.resource)
            tree[perm.category]["permissions"].append(perm)
        
        # 转换为可序列化的格式
        result = {}
        for category, data in tree.items():
            result[category] = {
                "actions": sorted(list(data["actions"])),
                "resources": sorted(list(data["resources"])),
                "permissions": [perm.to_dict() for perm in data["permissions"]]
            }
        
        return result
    
    def create_system_permissions(self) -> List[Permission]:
        """创建系统默认权限"""
        system_permissions = [
            # 用户管理权限
            {"name": "user:create", "display_name": "创建用户", "category": "用户管理", "action": "create", "resource": "user"},
            {"name": "user:read", "display_name": "查看用户", "category": "用户管理", "action": "read", "resource": "user"},
            {"name": "user:update", "display_name": "更新用户", "category": "用户管理", "action": "update", "resource": "user"},
            {"name": "user:delete", "display_name": "删除用户", "category": "用户管理", "action": "delete", "resource": "user"},
            
            # 角色管理权限
            {"name": "role:create", "display_name": "创建角色", "category": "角色管理", "action": "create", "resource": "role"},
            {"name": "role:read", "display_name": "查看角色", "category": "角色管理", "action": "read", "resource": "role"},
            {"name": "role:update", "display_name": "更新角色", "category": "角色管理", "action": "update", "resource": "role"},
            {"name": "role:delete", "display_name": "删除角色", "category": "角色管理", "action": "delete", "resource": "role"},
            
            # 权限管理权限
            {"name": "permission:create", "display_name": "创建权限", "category": "权限管理", "action": "create", "resource": "permission"},
            {"name": "permission:read", "display_name": "查看权限", "category": "权限管理", "action": "read", "resource": "permission"},
            {"name": "permission:update", "display_name": "更新权限", "category": "权限管理", "action": "update", "resource": "permission"},
            {"name": "permission:delete", "display_name": "删除权限", "category": "权限管理", "action": "delete", "resource": "permission"},
            
            # 工具管理权限
            {"name": "tool:create", "display_name": "创建工具", "category": "工具管理", "action": "create", "resource": "tool"},
            {"name": "tool:read", "display_name": "查看工具", "category": "工具管理", "action": "read", "resource": "tool"},
            {"name": "tool:update", "display_name": "更新工具", "category": "工具管理", "action": "update", "resource": "tool"},
            {"name": "tool:delete", "display_name": "删除工具", "category": "工具管理", "action": "delete", "resource": "tool"},
            
            # 任务管理权限
            {"name": "task:create", "display_name": "创建任务", "category": "任务管理", "action": "create", "resource": "task"},
            {"name": "task:read", "display_name": "查看任务", "category": "任务管理", "action": "read", "resource": "task"},
            {"name": "task:update", "display_name": "更新任务", "category": "任务管理", "action": "update", "resource": "task"},
            {"name": "task:delete", "display_name": "删除任务", "category": "任务管理", "action": "delete", "resource": "task"},
        ]
        
        created_permissions = []
        for perm_data in system_permissions:
            existing = self.get_by_name(perm_data["name"])
            if not existing:
                permission = Permission(
                    **perm_data,
                    is_system=True,
                    is_active=True
                )
                self.db.add(permission)
                created_permissions.append(permission)
        
        self.db.commit()
        return created_permissions